home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / mscheap2 / bench.c next >
C/C++ Source or Header  |  1990-03-13  |  5KB  |  226 lines

  1. //
  2. //     Copyright (c) 1990 by Optimal Software, All Rights Reserved
  3. //
  4.  
  5. //
  6. //    This program is a simple benchmark for heap management
  7. //
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13.  
  14. #include <heap.h>
  15.  
  16. //
  17. //    Declare globals so that linking with original heap manager does not
  18. //    produce undefined symbols.
  19. //
  20.  
  21. int    _heapmode;
  22.  
  23. size_t _heappad ;
  24.  
  25. static void exercise( long iterations );
  26.  
  27. /******************************************************************************/
  28. //
  29. //  Exercise the heap manager
  30. //
  31. int main( int argc, char *argv[] )
  32. {
  33. switch( argc )
  34.    {
  35.    case 4: _heappad  = atoi( argv[3] );   /* 'ware fall through */
  36.  
  37.    case 3: _heapmode = atoi( argv[2] );   /* 'ware fall through */
  38.  
  39.    case 2: exercise( atol( argv[1] ) );
  40.  
  41.            break;
  42.  
  43.    default: fprintf( stderr, "Usage: bench iteration_count [heapmode] [heappad]\n" );
  44.    }
  45.  
  46. return( 0 );
  47. }
  48. /******************************************************************************/
  49. static void exercise( long iterations )
  50. {
  51. typedef struct block
  52.    {
  53.    struct block far *next;
  54.    struct block far *last;
  55.    } BLOCK;
  56.  
  57. int status;
  58.  
  59. long count=iterations, fails=0;
  60.  
  61. time_t seconds = time(NULL);
  62.  
  63. BLOCK far *tmp, far *list = _fmalloc( sizeof(BLOCK) );
  64.  
  65. list->next = list;
  66. list->last = list;
  67.  
  68. srand(12345);
  69.  
  70. while (count--)
  71.    {
  72.    int skew, todo;
  73.  
  74.    size_t size = sizeof(BLOCK);
  75.  
  76.    /*/
  77.       Mimic the natural emphasis on small chunks by generating an offset
  78.       with a triangular distribution.  The difference of randoms creates
  79.       a square of results with zeros on the diagonal.  Suppressing the
  80.       negative values leaves a triangle with 32768 zeros on the diagonal,
  81.       a single 32767 in the corner, and a range of intermediate values.
  82.       Every value {N:0..32767} appears 32768-N times.
  83.    /*/
  84.    do
  85.       {
  86.       skew = rand() - rand();
  87.       }
  88.    while (skew < 0);
  89.  
  90.    size += rand() % (uint) (skew+1);
  91.  
  92.    todo = rand() % 6; /* 3 parts malloc    (more than free so heap grows)
  93.                          2 parts free
  94.                          1 part  realloc   (also tests _expand) */
  95.  
  96.    if (list->next == list)
  97.  
  98.       todo = 0;          /* list is empty, malloc something! */
  99.  
  100.    switch( todo )
  101.  
  102.       {
  103.       case 0 : /* malloc */
  104.       case 1 :
  105.       case 2 : tmp = (BLOCK far *) _fmalloc(size);
  106.  
  107.                if (tmp != NULL)
  108.                   {   
  109.                   tmp->next = list->next;       /* insert new item in list */
  110.                   tmp->last = list;
  111.  
  112.                   tmp->next->last = tmp;
  113.                   tmp->last->next = tmp;
  114.                   }
  115.                else
  116.  
  117.                   fails++;                      /* oops, no room in heap */
  118.  
  119.                break;
  120.  
  121.       case 3: /* free */
  122.       case 4: tmp = list->next;
  123.  
  124.               tmp->next->last = tmp->last;  /* delete from list */
  125.               tmp->last->next = tmp->next;
  126.  
  127.               _ffree(tmp);
  128.  
  129.               break;
  130.  
  131.       case 5: /* realloc */
  132.               tmp = list->next;             /* pick a victim */
  133.  
  134.               tmp->next->last = tmp->last;  /* delete from list in case of failure */
  135.               tmp->last->next = tmp->next;
  136.  
  137.               tmp = _hrealloc(tmp, (long) size ); /* change size and possibly address */
  138.  
  139.               if (tmp != NULL)
  140.                  {
  141.                  tmp->next = list->next;    /* insert back into list */
  142.                  tmp->last = list;
  143.  
  144.                  tmp->next->last = tmp;
  145.                  tmp->last->next = tmp;
  146.                  }
  147.               else
  148.  
  149.                  fails++;                   /* oops */
  150.  
  151.               break;
  152.  
  153.       } /* switch */
  154.  
  155.    //
  156.    //    Move around in the list to avoid emulating a stack.
  157.    //
  158.    list = list->next;
  159.    }
  160.  
  161. seconds = time(NULL) - seconds;
  162.  
  163. if ( (status = _fheapset(-1) ) != _HEAPOK)
  164.  
  165.    printf("Heap error: %s\n", _heapstat( status ) );
  166.  
  167. else
  168.    {
  169. //   //
  170. //   //    This code implements an MSC-compatible heap inspection using
  171. //   //    _heapwalk() to traverse the heap entries.
  172. //   //
  173. //   struct _heapinfo hp;
  174. //
  175. //   int status;
  176. //
  177. //   hp._pentry = NULL;
  178. //
  179. //   while ( (status = _fheapwalk( &hp ) ) == _HEAPOK)
  180. //
  181. //      printf("%5u at %Fp %s\n",
  182. //             hp._size,
  183. //             hp._pentry,
  184. //             hp._useflag ? "" : "free" );
  185.  
  186.    //
  187.    //    Announce results
  188.    //
  189.    printf("\n%ld iterations, %ld failures, %ld seconds\n\n",
  190.           iterations,
  191.           fails,
  192.           seconds );
  193.  
  194. //   //
  195. //   //    This code implements a clean-up operation that is necessary if
  196. //   //    the exercise function is to be called more than once.  As the
  197. //   //    current implementation uses only one pass, this code is unnecessary.
  198. //   //
  199. //   //    Note: there is no MSC version of heapdump().
  200. //   //
  201. //   printf("Final heap state\n\n");
  202. //
  203. //   _heapdump( stdout, TRUE );
  204. //
  205. //   while (list->next != list)
  206. //      {
  207. //      BLOCK far *tmp = list->next;
  208. //
  209. //      tmp->next->last = tmp->last;
  210. //      tmp->last->next = tmp->next;
  211. //
  212. //      free(tmp);
  213. //      }
  214. //
  215. //   free(list);
  216. //
  217. //   _heappack();
  218. //
  219. //   printf("Post-cleanup heap state\n\n");
  220. //
  221. //   _heapdump( stdout, TRUE );
  222.    }
  223. }
  224. /******************************************************************************/
  225.  
  226.